#include "zucmotcfg.h" /* ZUCMOT_ERROR_NUM,LEN */
#include "motion.h"    /* these decls */
#include "dbuf.h"
#include "stashf.h"

int zucmotErrorInit(zucmot_error_t* errlog)
{
    if (errlog == 0)
    {
        return -1;
    }

    errlog->head = 0;
    errlog->start = 0;
    errlog->end = 0;
    errlog->num = 0;
    errlog->tail = 0;

    return 0;
}

int zucmotErrorPutfv(zucmot_error_t* errlog, unsigned char type, int errcode, const char* fmt, va_list ap)
{
    struct dbuf errbuf;
    struct dbuf_iter it;
    va_list ap_bk;
    va_copy(ap_bk, ap);

    if (errlog == 0 || errlog->num == ZUCMOT_ERROR_NUM)
    {
        /* full */
        return -1;
    }

    errlog->head++;
    errlog->type[errlog->end] = type;
    errlog->errcode[errlog->end] = errcode;
    dbuf_init(&errbuf, (unsigned char*)errlog->error[errlog->end], ZUCMOT_ERROR_LEN);
    dbuf_iter_init(&it, &errbuf);
    vstashf(&it, fmt, ap_bk);

    errlog->end = (errlog->end + 1) % ZUCMOT_ERROR_NUM;
    errlog->num++;

    errlog->tail = errlog->head;

    return 0;
}

int zucmotErrorPutf(zucmot_error_t* errlog, unsigned char type, int errcode, const char* fmt, ...)
{
    int result;
    va_list ap;
    va_start(ap, fmt);
    result = zucmotErrorPutfv(errlog, type, errcode, fmt, ap);
    va_end(ap);
    return result;
}

int zucmotErrorPut(zucmot_error_t* errlog, unsigned char type, int errcode, const char* error) { return zucmotErrorPutf(errlog, type, errcode, "%s", error); }

int zucmotErrorGet(zucmot_error_t* errlog, unsigned char* ptype, int* perrcode, char* error)
{
    if (errlog == 0 || errlog->num == 0)
    {
        /* empty */
        return -1;
    }

    errlog->head++;
    *ptype = errlog->type[errlog->start];
    *perrcode = errlog->errcode[errlog->start];  // get the error code
    memcpy(error, errlog->error[errlog->start], ZUCMOT_ERROR_LEN);
    errlog->start = (errlog->start + 1) % ZUCMOT_ERROR_NUM;
    errlog->num--;
    errlog->tail = errlog->head;

    return 0;
}
